<template>
  <div class="data-preview">
    <el-container>
      <!-- 顶部操作栏 -->
      <el-header class="preview-header">
        <el-button class="close-button" type="danger" @click="handleClose">
          <el-icon class="el-icon--left"><CircleCloseFilled /></el-icon>
          关闭
        </el-button>
        <div class="header-left">
          <span v-if="currentTable" class="current-table">
            {{ currentTable.tableName }}
          </span>
        </div>
        <h2 style="margin-right: 40px">数据预览</h2>
      </el-header>

      <!-- 下方表结构树和表数据展示 -->
      <el-container class="main-container">
        <el-aside width="240px">
          <div class="tree-container">
            <div class="search-container">
              <el-input class="search-input" v-model="searchText" placeholder="搜索" :prefix-icon="Search" clearable/>
            </div>
            <el-tree class="database-tree" ref="treeRef" :data="treeData" :props="treeProps" :load="loadNode" :filter-node-method="filterNode"
                @node-click="handleNodeClick" @node-expand="handleExpand" @node-collapse="handleCollapse" v-loading="treeLoading">
              <template #default="{ node, data }">
                <span class="tree-node">
                  <span v-if="data.type === 'database'" class="database-icon-wrapper">
                    <el-icon class="database-icon" :class="{ 'is-expanded': expandedNodes.has(node.id) }">
                      <Folder v-if="!expandedNodes.has(node.id)" />
                      <FolderOpened v-else />
                    </el-icon>
                  </span>
                  <el-icon v-else-if="data.type === 'table'" class="table-icon">
                    <Document />
                  </el-icon>
                  <span class="node-label">{{ node.label }}</span>
                </span>
              </template>
            </el-tree>
          </div>
        </el-aside>

        <el-main class="table-main">
          <div class="table-container">
            <el-table v-if="currentTable" v-loading="tableLoading" :data="tableData"
                stripe height="calc(100vh - 80px)" class="data-table">
              <el-table-column v-for="column in tableColumns" :key="column.prop" :prop="column.prop" :label="column.label"
                               show-overflow-tooltip width="180"/>
            </el-table>
            <div v-else class="empty-tip">
              <el-icon class="empty-icon"><Document /></el-icon>
              <p>请选择要预览的数据表</p>
            </div>
          </div>
        </el-main>
      </el-container>
    </el-container>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { Folder, FolderOpened, Document, CircleCloseFilled, Search } from '@element-plus/icons-vue'
import { connectionPathTable, connectionPathTableData } from '@/api/connection'

// 添加类型定义
enum PathType {
  PATH = 'path',
  TABLE = 'table'
}

enum TableType {
  TABLE = 'TABLE',
  VIEW = 'VIEW'
}

interface PathTableNode {
  pathType: PathType
  name: string
  remarks?: string
  tableType?: TableType
  children?: PathTableNode[]
}

interface DatabaseNode {
  id: string
  label: string
  type: 'database'
  connectionId: number
}

interface TableNode {
  id: string
  label: string
  type: 'table'
  databaseName: string
  tableName: string
}

// 树形结构配置
const treeProps = {
  label: 'label',
  children: 'children',
  isLeaf: (data: DatabaseNode | TableNode) => data.type === 'table'
}

const treeData = ref<(DatabaseNode | TableNode)[]>([])
const treeLoading = ref(false)
const tableLoading = ref(false)
const currentTable = ref<TableNode | null>(null)
const tableData = ref<any[]>([])
const tableColumns = ref<{ prop: string; label: string }[]>([])

// 添加 tree 引用
const treeRef = ref()

// 添加展开节点集合
const expandedNodes = ref(new Set<string>())

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 初始化事件 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 生命周期事件 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
onMounted(() => {
  loadNode()
})

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 控件事件 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// 加载树节点数据
const loadNode = async () => {
  treeLoading.value = true
  try {
    // 获取数据库和表结构数据
    const data = await connectionPathTable(props.id)

    // 转换数据格式为树形结构
    const convertToTreeNode = (node: PathTableNode): DatabaseNode | TableNode => {
      if (node.pathType === PathType.PATH) {
        return {
          id: node.name,
          label: node.name,
          type: 'database',
          connectionId: props.id,
          children: node.children?.map(convertToTreeNode)
        }
      } else {
        return {
          id: node.name,
          label: node.name,
          type: 'table',
          databaseName: node.remarks || '',  // 假设 remarks 存储了数据库名称
          tableName: node.name
        }
      }
    }

    treeData.value = data.map(convertToTreeNode)
  } catch (error) {
    ElMessage.error('获取数据库结构失败')
  } finally {
    treeLoading.value = false
  }
}

// 添加获取父路径的方法
const getNodePaths = (node: any): string[] => {
  const paths: string[] = []
  let currentNode = node.parent

  // 遍历父节点直到根节点
  while (currentNode && currentNode.data) {
    // 只收集类型为 'database' 的节点名称
    if (currentNode.data.type === 'database') {
      paths.unshift(currentNode.data.label) // 将路径添加到数组开头
    }
    currentNode = currentNode.parent
  }

  return paths
}

// 修改处理节点点击的方法
const handleNodeClick = async (data: DatabaseNode | TableNode, node: any) => {
  if (data.type === 'table') {
    currentTable.value = data
    tableLoading.value = true
    try {
      // 获取所有父路径
      const paths = getNodePaths(node)

      const previewData = await connectionPathTableData(props.id, {
        'path': paths,
        'table': data.tableName
      })

      // 生成表格列
      if (previewData.data.length > 0) {
        const columns = []
        for (let i = 0; i <  previewData.schema.length; i++) {
          const item = previewData.schema[i]
          columns.push({
            prop: `${i}`,
            label: !!item.label ? item.label : item.fieldName
          })
        }
        tableColumns.value = columns
      } else {
        tableColumns.value = []
      }
      tableData.value = previewData.data
    } catch (error) {
      ElMessage.error('获取表数据失败')
    } finally {
      tableLoading.value = false
    }
  }
}

// 组件属性
const props = defineProps<{
  id: number
}>()

// 添加关闭事件
const emit = defineEmits(['close'])
const handleClose = () => {
  emit('close')
}

// 添加搜索功能
const searchText = ref('')
const filterNode = (value: string, data: DatabaseNode | TableNode) => {
  if (!value) return true
  return data.label.toLowerCase().includes(value.toLowerCase())
}

// 监听搜索文本变化
watch(searchText, (val) => {
  treeRef.value?.filter(val)
})

// 处理节点展开
const handleExpand = (data: DatabaseNode | TableNode, node: any) => {
  expandedNodes.value.add(node.id)
}

// 处理节点收起
const handleCollapse = (data: DatabaseNode | TableNode, node: any) => {
  expandedNodes.value.delete(node.id)
}
</script>

<style scoped>

.data-preview {
  height: 100vh;
  background-color: #f5f7fa;
}

.preview-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 60px;
  border-bottom: 1px solid #e4e7ed;
  position: relative;
}
/* 添加彩虹边框效果 */
.preview-header::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 2px;
  background: linear-gradient(                    /* 渐变色彩虹效果 */
      90deg,#2196f3,#66bb6a,#ffeb3b,#ff8f00,#ff4444,#2196f3
  ) !important;
  background-size: 300% 100% !important;          /* 渐变区域扩展以实现动画效果 */
  animation: moveGradient 6s linear infinite !important;  /* 应用彩虹移动动画 */
  z-index: 3;                                     /* 确保彩虹线显示在最上层 */
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.25);  /* 添加阴影效果: 单一柔和阴影 */
}

.preview-header h2 {
  margin: 0;
  font-size: 18px;
  color: #303133;
}

.header-left {
  display: flex;
  align-items: center;
}

.current-table {
  font-size: 18px;
  display: flex;
  justify-content: center;
}

.main-container {
  height: calc(100vh - 60px);
}

.search-container {
  position: sticky;           /* 或者使用 fixed */
  top: 0;                     /* 固定在顶部 */
  z-index: 10;                /* 确保在其他元素之上 */
  background-color: #fff; /* 确保背景色与树形结构一致 */
}

.tree-container {
  height: 100%;
  margin-left: 10px;
  background-color: #fff;
}

.tree-node {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 32px;
  border-radius: 4px;
  transition: background-color 0.2s ease;
}

.tree-node:hover {
  background-color: var(--el-fill-color-light);
}

:deep(.el-tree-node) {
  display: table;
  width: 100%;

}

.database-tree {
  height: 100%;
  flex-grow: 1;
  overflow: auto; /* 启用垂直滚动 */
}

.database-icon-wrapper {
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.database-icon {
  transition: all 0.3s ease-in-out;
  color: var(--el-text-color-secondary);
}

.database-icon.is-expanded {
  transform: rotate(0deg);
  color: var(--el-color-primary);
}

/* 添加图标切换动画 */
.el-icon {
  transition: transform 0.3s ease-in-out, color 0.3s ease-in-out;
}

.table-icon {
  color: var(--el-text-color-secondary);
}

.node-label {
  font-size: 14px;
  color: var(--el-text-color-regular);
  transition: color 0.2s ease;
}

.tree-node:hover .node-label {
  color: var(--el-color-primary);
}

.table-main {
  background-color: #f5f7fa;
}

.table-container {
  height: 100%;
  background-color: #fff;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.data-table {
  width: 100%;
}

.empty-tip {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: #909399;
}

.empty-icon {
  font-size: 48px;
}

.empty-tip p {
  margin: 0;
  font-size: 14px;
}

:deep(.el-aside) {
  margin: 10px 0px 10px 0px;  
}

:deep(.el-main) {
  padding: 10px;
}

:deep(.el-table) {
  border-radius: 4px;
}

:deep(.el-table th) {
  background-color: #f5f7fa;
  color: #606266;
  font-weight: 600;
}

:deep(.el-table--striped .el-table__body tr.el-table__row--striped td) {
  background-color: #fafafa;
}





</style>